package com.google.code.jholidays.events;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import java.util.Calendar;
import java.util.Date;

import org.junit.Test;

import com.google.code.jholidays.core.EventDescriptor;
import com.google.code.jholidays.events.parameters.Offset;
import com.google.code.jholidays.events.properties.DependentEventProperties;
import com.google.code.jholidays.moc.FixedEventMoc;

/**
 * Uses {@link FixedEventMoc} in order to verify getDate() against predictable
 * parent date
 * 
 * @author tillias
 * 
 */
public class DependentEventTest {

    @Test(expected = IllegalArgumentException.class)
    public void testNullProperties() {

	DependentEvent event = new DependentEvent(null);
	assertNull(event);
    }

    @Test
    public void testCreateValidDependetEvent() {
	final int dependentEventID = 1;
	final int parentEventID = 2;

	Offset offset = new Offset(1);

	EventDescriptor dependentEventDescriptor = new EventDescriptor(
		dependentEventID, parentEventID);

	IEvent parentEvent = new FixedEventMoc(parentEventID);
	assertEquals(parentEvent.getID(), dependentEventDescriptor
		.getParentID());

	DependentEventProperties props = new DependentEventProperties(
		dependentEventDescriptor, parentEvent, offset);
	DependentEvent event = new DependentEvent(props);
	assertNotNull(event);

	// verify fiels of event
	assertEquals(event.getID(), dependentEventID);
	assertSame(event.getDescriptor(), dependentEventDescriptor);
	assertSame(event.getParent(), parentEvent);
	assertSame(event.getOffset(), offset);
    }

    @Test
    public void testGetDate() {
	final int parentID = 1;
	final int eventID = 2;

	// create fixed parent event
	IEvent parentEvent = createFixedEvent(parentID);
	assertEquals(parentEvent.getID(), parentID);

	EventDescriptor descriptor = new EventDescriptor(eventID, parentID);

	Offset offset = new Offset(1);
	DependentEventProperties props = new DependentEventProperties(
		descriptor, parentEvent, offset);
	DependentEvent event = new DependentEvent(props);
	assertNotNull(event);

	// verify date
	final int year = 2009;

	Date parentDate = parentEvent.getDate(year);

	Date eventDate = event.getDate(year);

	// check agains offset
	Calendar c = Calendar.getInstance();
	c.clear();
	c.setTime(parentDate);
	c.add(Calendar.DATE, offset.getDaysCount());

	assertEquals(eventDate, c.getTime());

	// check against parent date
	c = Calendar.getInstance();
	c.clear();
	c.setTime(eventDate);
	c.add(Calendar.DATE, -offset.getDaysCount());

	assertEquals(parentDate, c.getTime());
    }

    @Test
    public void testGetOffset() {
	final int parentID = 1;
	final int eventID = 2;

	// create fixed parent event
	IEvent parentEvent = createFixedEvent(parentID);
	assertEquals(parentEvent.getID(), parentID);

	EventDescriptor descriptor = new EventDescriptor(eventID, parentID);

	Offset offset = new Offset(1);

	DependentEventProperties props = new DependentEventProperties(
		descriptor, parentEvent, offset);
	DependentEvent event = new DependentEvent(props);
	assertNotNull(event);

	assertSame(offset, event.getOffset());
    }

    protected IEvent createFixedEvent(int id) {
	return new FixedEventMoc(id);
    }
}
